#include "board.h"
#include <FreeRTOS.h>
#include "task.h"
#include "portmacro.h"
#include "rfparam_adapter.h"
#include "btble_lib_api.h"
#include "bl616_glb.h"
#include "bt_log.h"
#include "bluetooth.h"
#include "conn.h"
#include "conn_internal.h"
#include "hci_driver.h"
#include "hci_core.h"
#include "gatt.h"
#include "semphr.h"

#include "bflb_uart.h"
#include "bflb_dma.h"

struct bt_conn *ble616_conn;                    // ble连接设备结构体
uint8_t ble_conn_flag = 0;
static struct bflb_device_s *uartx;             // BL616通过串口0与BL618主控通信

uint8_t value_recv_write[1] = {0x30};
uint8_t value_recv_read[1] =  {0x00};
static int ble_recv_read(struct bt_conn *conn,	const struct bt_gatt_attr *attr,
                                        void *buf, u16_t len, u16_t offset)
{
    value_recv_read[0] = bflb_uart_getchar(uartx);
    memcpy(buf, value_recv_read, sizeof(value_recv_read));
    
    return 1;//必须是1才能成功读
}

static int ble_recv_write(struct bt_conn *conn,	const struct bt_gatt_attr *attr,
                                        void *buf, u16_t len, u16_t offset)
{
    memcpy(value_recv_write, buf, sizeof(value_recv_write));
    bflb_uart_putchar(uartx,value_recv_write[0]);
    return 0;
}

#define MyServer1 BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x07af27b1,0x9c22,0x11ea,0x9afe,0x02fcdc4e7412))
#define MyServer1CHAR1 BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x07af27c1,0x9c22,0x11ea,0x9afe,0x02fcdc4e7412))
static struct bt_gatt_attr attrs1[]= {
    BT_GATT_PRIMARY_SERVICE(MyServer1),
        BT_GATT_CHARACTERISTIC(MyServer1CHAR1,
							BT_GATT_CHRC_READ |BT_GATT_CHRC_WRITE |BT_GATT_CHRC_WRITE_WITHOUT_RESP,
							BT_GATT_PERM_READ |BT_GATT_PERM_WRITE |BT_GATT_PERM_PREPARE_WRITE,
							ble_recv_read,
							ble_recv_write,
							NULL),
        
};

struct bt_gatt_service ble_server = BT_GATT_SERVICE(attrs1);        // 注册服务

static void ble_connected(struct bt_conn *conn, u8_t err)
{
    if(err || conn->type != BT_CONN_TYPE_LE)
    {
        return;
    }
    ble_conn_flag = 1;

    struct bflb_device_s *gpio;
    gpio = bflb_device_get_by_name("gpio");
    bflb_gpio_uart_init(gpio, GPIO_PIN_21, GPIO_UART_FUNC_UART0_TX);
    bflb_gpio_uart_init(gpio, GPIO_PIN_22, GPIO_UART_FUNC_UART0_RX);
    uartx = bflb_device_get_by_name("uart0");
    struct bflb_uart_config_s cfg;
    cfg.baudrate = 2000000;
    cfg.data_bits = UART_DATA_BITS_8;
    cfg.stop_bits = UART_STOP_BITS_1;
    cfg.parity = UART_PARITY_NONE;
    cfg.flow_ctrl = 0;
    cfg.tx_fifo_threshold = 0;
    cfg.rx_fifo_threshold = 0;
    
    bflb_uart_init(uartx, &cfg);
    bflb_uart_putchar(uartx,32);
}

static void ble_disconnected(struct bt_conn *conn, u8_t reason)
{ 
    if(conn->type != BT_CONN_TYPE_LE)
    {
        return;
    }
    bflb_uart_putchar(uartx,33);
    bflb_uart_deinit(uartx);
    ble_conn_flag = 0;
    set_adv_enable(true);              // 断开连接重新广播
    
}

static struct bt_conn_cb ble_conn_callbacks = {
	.connected	=   ble_connected,
	.disconnected	=   ble_disconnected,
};

static void ble_start_adv(void)
{
    struct bt_le_adv_param adv_param = {
        .options = (BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_ONE_TIME ),
    //BT_LE_ADV_OPT_CONNECTABLE和BT_LE_ADV_OPT_ONE_TIME一起用 连接后才能自动停止广播
    //BT_LE_ADV_OPT_USE_NAME使用设备名称BTBLE-DVE 则不能使用自定义名称BT_DATA_NAME_COMPLETE
        .interval_min = BT_GAP_ADV_FAST_INT_MIN_2,//100ms
        .interval_max = BT_GAP_ADV_FAST_INT_MAX_2,//150ms
    };

    //一串广播包37字节  前6字节为MAC地址 后31字节为若干个数据结构体，AD structure  未全补0
    uint8_t adv_name[] = {"智能护颈助手"};//如果用中文是一个汉字3字节 注意长度
    uint8_t data_type[1] = {(BT_LE_AD_NO_BREDR | BT_LE_AD_GENERAL)};//设备标识
    uint8_t data_uuid[2] = {0x12, 0x18};//0x1812

    //广播包
    struct bt_data adv_data[] = {
            BT_DATA(BT_DATA_FLAGS, data_type, 1),
            //第一个包   长度0x02   类型0x01   数据0x06(0x04+0x02=0x06)
            //长度Length 1字节(内容等于1+N)    类型type(1字节)    数据data(N字节)
            //广播类型
            //0x01 设备标识
            //0x02 16bit UUID
            //0x07 128bit UUID
            //0x08 略缩设备名称
            //0x09 完整设备名称  UTF-8
            //0x0A 发射功率
            //0x19 设备外观
            //0xFF 厂商自定义数据

            BT_DATA(BT_DATA_UUID16_ALL, data_uuid, sizeof(data_uuid)),
            //第二个包 完整16lit UUID  类型0x03

            BT_DATA(BT_DATA_NAME_COMPLETE, adv_name, strlen(adv_name)),
            //第三个包 自定义完整设备名称 类型0x09 采用UTF-8编码
        };
    //广播响应包
    struct bt_data adv_rsp[] = {
        // 不够可以使用响应包
    };

    bt_le_adv_start(&adv_param, adv_data, ARRAY_SIZE(adv_data), adv_rsp, ARRAY_SIZE(adv_rsp));
}

void bt_enable_cb(int err)
{
    if (!err) 
    {
        bt_addr_le_t bt_addr;
        bt_get_local_public_address(&bt_addr);
        //printf("BD_ADDR:(MSB)%02x:%02x:%02x:%02x:%02x:%02x(LSB) \r\n",
        //    bt_addr.a.val[5], bt_addr.a.val[4], bt_addr.a.val[3], bt_addr.a.val[2], bt_addr.a.val[1], bt_addr.a.val[0]);
        //MAC地址6字节 B4:0E:CF:2A:E9:BC

        bt_conn_cb_register(&ble_conn_callbacks);       // 注册连接回调函数
        bt_gatt_service_register(&ble_server);          // 注册服务


        ble_start_adv();                                // 开始广播
    }
}

static int btblecontroller_em_config(void)
{
    extern uint8_t __LD_CONFIG_EM_SEL;
    volatile uint32_t em_size;

    em_size = (uint32_t)&__LD_CONFIG_EM_SEL;

    if (em_size == 0) {
        GLB_Set_EM_Sel(GLB_WRAM160KB_EM0KB);
    } else if (em_size == 32*1024) {
        GLB_Set_EM_Sel(GLB_WRAM128KB_EM32KB);
    } else if (em_size == 64*1024) {
        GLB_Set_EM_Sel(GLB_WRAM96KB_EM64KB);
    } else {
        GLB_Set_EM_Sel(GLB_WRAM96KB_EM64KB);
    }

    return 0;
}

int main(void)
{
    board_init();                                      // 板级初始化
    configASSERT((configMAX_PRIORITIES > 4));

    // Initialize BLE phy rf
    if (0 != rfparam_init(0, NULL, 0))                 // 射频初始化
    {
        //printf("PHY RF init failed!\r\n");
        return 0;
    }
    // Initialize BLE controller
    btble_controller_init(configMAX_PRIORITIES - 1);    //controller层初始化
    btblecontroller_em_config();                        //设置ble controller EM Size
    // Initialize BLE Host stack
    hci_driver_init();                                  //HCI接口驱动初始化
    bt_enable(bt_enable_cb);
    
    vTaskStartScheduler();                              //启动调度器
    
    while (1)
    {
        //
    }
}
